package com.wzy.realm;

import com.wzy.pojo.User;
import com.wzy.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.Set;

/**
 * 先实现认证
 * 再实现授权
 */
public class MyRealm extends AuthorizingRealm {

    UserService userService = new UserService();

    /**
     * 实现授权
     *
     * 因为Shiro中配置多个 Realm，所以身份信息可能就有多个；
     * 因此其提供了 PrincipalCollection 用于聚合这些身份信息。
     * @param principalCollection
     * @return
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        //获取用户名
        String username = (String) principalCollection.getPrimaryPrincipal();

        //从数据库获取角色信息和权限信息
        Set<String> roles = userService.findRolesByUsername(username);
        Set<String> permissions = userService.findPermissionsByUsername(username);

        //创建SimpleAuthorizationInfo对象，设置角色和权限，并返回
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        authorizationInfo.setStringPermissions(permissions);

        return authorizationInfo;
    }

    /**
     * 实现认证
     *
     * 返回一个AuthenticationInfo对象
     * AuthenticationInfo对象中存储的是主体（Subject）的身份认证信息。
     * Shiro会调用CredentialsMatcher对象的doCredentialsMatch方法对AuthenticationInfo对象和AuthenticationToken进行匹配。
     * 匹配成功则表示主体（Subject）认证成功，否则表示认证失败。
     * 一般返回 SimpleAuthenticationInfo 即可。
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //从token中获取用户名
        String username = (String) authenticationToken.getPrincipal();

        //从数据库获取用户信息
        User user = userService.findByUsername(username);

        if (null == user){
            return null;
        }
        //创建SimpleAuthenticationInfo对象，并返回
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),this.getName());

        return authenticationInfo;
    }
}
